<template>
  <div class="participant-window" @mouseenter="showControls" @mouseleave="hideControlsAfterDelay" :style="{border: castFullScreen ? '1px solid rgba(255, 0, 0, 0.3)' : '1px solid rgba(255, 255, 255, 0.2)'}">
    <span style="color: #fffff1 ; font-size: 12px ; line-height: 12px; margin-left: 5px; margin-top: 5px; position: absolute; ">
      <font-awesome-icon :icon="['fas', 'user-tie']" style="color: #0052d9; width: 13px; height: 13px"
                         v-if="participant.id === room.ownerId"/> {{ participant.nickname }}</span>
    <video ref="remoteVideo" autoplay/>
    <div class="video-controls" :class="{ 'controls-visible': showControlsFlag }">
      <div class="control-btn" v-if="room.ownerId === self.id" :style="{ backgroundColor:'rgba(255, 0, 0, 0.3)' }" @click="kick(participant)">
        <font-awesome-icon :icon="['fas', 'user-slash']" :style="{ color: 'red' }"/>
      </div>
      <div class="control-btn" v-if="!castFullScreen"  :style="{ backgroundColor: 'rgba(34, 34, 34, 0.3)' }" @click="toggleFullScreen">
        <font-awesome-icon :icon="['fas', 'up-right-and-down-left-from-center']"  :style="{ color: '#222' }"/>
      </div>
      <div class="control-btn" v-if="castFullScreen" :style="{ backgroundColor: 'rgba(255, 0, 0, 0.3)' }" @click="toggleFullScreen">
        <font-awesome-icon :icon="['fas', 'down-left-and-up-right-to-center']"  :style="{ color: 'red' }"/>
      </div>
    </div>
  </div>
</template>

<script>
import {
  reportGroupChatParticipantAnswer,
  reportGroupChatParticipantCandidate,
  reportGroupChatParticipantOffer,
  subGroupChatParticipantAnswer,
  subGroupChatParticipantCandidate,
  subGroupChatParticipantOffer,
  unSubGroupChatParticipantAnswer,
  unSubGroupChatParticipantCandidate,
  unSubGroupChatParticipantOffer
} from "@/api/nats/group_chat";

export default {
  name: 'ParticipantWindow',
  inject: ['localStream'],
  props: {
    participant: {
      type: Object,
      default: () => {
      }
    },
    roomId: {
      type: String,
      default: () => {
      }
    },
    self: {
      type: Object,
      default: () => {
      }
    },
    kick: {
      type: Function
    },
    room: {
      type: Object,
      default: () => {
      }
    },
    participantCastFullScreen:{
      type: Function
    },
    participantCancelFullScreen: {
      type: Function
    }
  },
  data() {
    return {
      showControlsFlag: false,
      hideTimer: null,
      castFullScreen: false,
      peer: new RTCPeerConnection({
        iceServers: [
          {urls: 'stun:stun.l.google.com:19302'},
          {urls: 'stun:stun1.l.google.com:19302'},
          {urls: 'stun:stun2.l.google.com:19302'}
        ],
      }),
    }
  },
  methods: {
    init() {
      this.subscribe();
      this.initPeer();
    },
    subscribe() {
      subGroupChatParticipantOffer(this.roomId, this.participant.id, this.self.id, this.receivedParticipantOffer)
      subGroupChatParticipantAnswer(this.roomId, this.participant.id, this.self.id, this.receivedParticipantAnswer)
      subGroupChatParticipantCandidate(this.roomId, this.participant.id, this.self.id, this.receivedParticipantCandidate)
    },
    initPeer() {
      this.setPeerMediaTrack();
      this.peer.onicecandidate = e => {
        if (e.candidate) {
          reportGroupChatParticipantCandidate(this.roomId, this.self.id, this.participant.id, {
            type: "candidate",
            roomId: this.roomId,
            fromParticipant: this.self,
            toParticipant: this.participant,
            candidate: e.candidate
          })
        }
      }
      this.peer.ontrack = e => {
        if (e.streams[0]) {
          this.$nextTick(() => {
            this.$refs.remoteVideo.srcObject = e.streams[0];
            if (this.castFullScreen) {
              this.participantCastFullScreen(this.participant)
            }
          })
        }
      }
    },
    setPeerMediaTrack() {
      let stream = this.localStream.using === 'camera' ? this.localStream.cameraStream : this.localStream.screenStream;
      stream.getTracks().forEach(track => {
        this.peer.addTrack(track, stream);
      })
    },
    resetPeerMediaTrack() {
      this.peer.getSenders().forEach(sender => {
        if (sender.track) {
          this.peer.removeTrack(sender);   // 标记为“不再发送”
        }
      });
      this.setPeerMediaTrack();
      this.sendOffer(true, true)
    },
    async sendOffer(offerToReceiveAudio = true, offerToReceiveVideo = true) {
      let offer = await this.peer.createOffer({
        offerToReceiveAudio,
        offerToReceiveVideo
      });
      await this.peer.setLocalDescription(offer);
      reportGroupChatParticipantOffer(this.roomId, this.self.id, this.participant.id, {
        type: "offer",
        roomId: this.roomId,
        fromParticipant: this.self,
        toParticipant: this.participant,
        offer: offer
      })
    },
    async receivedParticipantOffer(data) {
      let {offer, fromParticipant} = data;
      if (fromParticipant.id !== this.participant.id) {
        return
      }
      await this.peer.setRemoteDescription(new RTCSessionDescription(offer));
      let answer = await this.peer.createAnswer();
      await this.peer.setLocalDescription(answer);
      reportGroupChatParticipantAnswer(this.roomId, this.self.id, this.participant.id, {
        type: "answer",
        roomId: this.roomId,
        fromParticipant: this.self,
        toParticipant: this.participant,
        answer: answer
      })
    },
    async receivedParticipantAnswer(data) {
      let {answer, fromParticipant} = data;
      if (fromParticipant.id !== this.participant.id) {
        return
      }
      await this.peer.setRemoteDescription(new RTCSessionDescription(answer));
    },
    async receivedParticipantCandidate(data) {
      let {candidate, fromParticipant} = data;
      if (fromParticipant.id !== this.participant.id) {
        return
      }
      await this.peer.addIceCandidate(new RTCIceCandidate(candidate));
    },
    unsubscribe() {
      unSubGroupChatParticipantOffer(this.roomId, this.participant.id, this.self.id)
      unSubGroupChatParticipantAnswer(this.roomId, this.participant.id, this.self.id)
      unSubGroupChatParticipantCandidate(this.roomId, this.participant.id, this.self.id)
    },
    toggleFullScreen(){
      if (this.castFullScreen){
        this.participantCancelFullScreen()
      }else {
        this.participantCastFullScreen(this.participant)
      }
      this.castFullScreen = !this.castFullScreen;
    },
    resetFullScreen() {
      this.castFullScreen = false;
    },
    showControls() {
      clearTimeout(this.hideTimer);
      this.showControlsFlag = true;
    },
    // 2s 后隐藏控件组
    hideControlsAfterDelay() {
      this.hideTimer = setTimeout(() => {
        this.showControlsFlag = false;
      }, 1000);
    },
  },
  watch: {
    'localStream.using'(newValue, oldValue) {
      if (newValue !== oldValue) {
        this.resetPeerMediaTrack();
      }
    }
  },
  mounted() {
    this.init();
  },
  beforeDestroy() {
    this.unsubscribe();
    this.peer.close();
    this.peer = null;
  }
}
</script>


<style scoped>

.participant-window {
  width: calc(100% - 2px);
  height: 170px;
  flex-shrink: 0;
  border-radius: 10px;
  overflow: hidden;
  position: relative;
  z-index: 5;
  border: 1px solid rgba(255, 255, 255, 0.2);
  transition: none;

  &:hover {
    background-color: rgba(255, 255, 255, 0.1);
  }
}

video {
  width: 100%;
  height: 100%;
  object-fit: fill;
}


.video-controls {
  position: absolute;
  bottom: 10px;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  gap: 10px;
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.3s, visibility 0.3s;
}

.controls-visible {
  opacity: 1;
  visibility: visible;
}


.control-btn{
  width: 40px;
  height: 40px;
  border-radius: 50%;
  display: flex;
  justify-content: center;
  align-items: center;
  backdrop-filter: blur(8px);
  cursor: pointer;
  transition: background-color 0.3s;
}

.control-btn:hover {
  background-color: rgba(255, 255, 255, 0.1);
}

</style>